動畫 : image_animate()

常用來調整動畫速度

#RStudio中用c()連結就有動畫效果,fps固定為1
#image_animate可透過fps調整動畫播放速度,以及重播次數
image_animate(image = c(pic1, pic2, pic3),
              fps = 2, 
              #loop = 300 ,
              dispose = "none")

#加入透明邊框巧妙使圖形產生位移
image_animate(image = c(pic1, pic2,image_border(pic3,"none","100X200")),
              fps = 2, dispose = "none")

dispose_types()
## [1] "Undefined"  "Background" "None"       "Previous"   "0"         
## [6] "1"          "2"          "3"

漸變效果

frams為每次漸變過程,間隔的圖片張數

#BMO.light → BMO.dark → BMO.light
frames <- image_morph(c(BMO.light, image_flop(BMO.dark), BMO.light), frames = 20)
length(frames)
## [1] 43
image_info(frames) %>% head
##   format width height colorspace matte filesize
## 1    PNG   720    720       sRGB  TRUE        0
## 2    PNG   720    720       sRGB  TRUE        0
## 3    PNG   720    720       sRGB  TRUE        0
## 4    PNG   720    720       sRGB  TRUE        0
## 5    PNG   720    720       sRGB  TRUE        0
## 6    PNG   720    720       sRGB  TRUE        0
image_append(c(frames[1],frames[11],frames[22]))

#利用image_animate調整動畫速度
BMO.morph <- image_animate(frames,fps = 10)
BMO.morph

將動畫嵌入靜圖

jake.gif <- image_read('https://media.giphy.com/media/G9AjdAf3cGmfS/giphy.gif') %>% image_crop("220X200+200+30") %>% image_scale("80")
jake.gif

#將jake.gif動畫加到AT靜圖上
AT %>% image_composite(jake.gif, operator = "over",offset = "+600+600") %>%
    image_animate(fps = 10)

將統計圖表進行後製

image_graph():開啟Magick的圖形裝置介面(GDI)

開啟圖形裝置介面後,統計圖表會繪製到GDI,就可以用Magick套件加工,輸出圖表後記得用dev.off()關閉裝置介面

figure <- image_graph(width = 700, height = 700, res = 96)
class(figure)
## [1] "magick-device" "magick-image"
ggplot2::qplot(carat,price,
               data =  diamonds[sample(1:50000,1000),],
               colour = color)
dev.off()
## png 
##   2
figure

mark1 <- pic3 %>% image_scale("150X150")
mark1

myfig1 <- image_composite(figure, mark1, offset = "+450+500")%>%
    image_animate(fps = 10,dispose = "none")
myfig1

mark2 <- jake.gif %>% image_scale("150X150")
mark2

myfig2 <- image_composite(figure, mark2, offset = "+450+500")%>%
    image_animate(fps = 10,dispose = "none")
myfig2

在Magick的GDI開啟圖片: image_draw()

image_draw利用Magic圖形裝置介面開啟圖片(Magick-Image),就能用同時用Magick套件低階繪圖函數進行後製,同樣後製完後記得用dev.off()關閉裝置介面

img <- image_draw(myfig2)

#Q abline能不能設邊界
abline(h = 200, col = 'red',lwd = '2', lty = "dotted")
abline(h = 300, col = 'blue',lwd = '2', lty = "dotted")

#rect逆時針左下右上,注意座標須改用像素座標系統,左上角為原點,像右為x軸正向,向下為y軸正向
rect(80, 650, 240, 500, border = "red", lty = "dashed", lwd = 5)

#加入註解,x、y設定文字方塊的寬跟高要多長
text(x = 30,y =  250, "Heisenberg", family = "monospace", cex = 4, srt = 90)

#也能用image_annotation加入註解
image_annotate(img,"Say my name",size = 80, gravity = "south")

dev.off()
## png 
##   2

時間序列動態視覺化

人均GDP對平均壽命的散佈圖,點大小隨人口數變化,洲以顏色區分,不同時間的散佈圖以動畫呈現

#各國人均GDP資料
library(gapminder)
head(gapminder)
#將資料按照年份進行分割
data.list <- split(gapminder, gapminder$year)
#用ggplot繪圖輸出到圖形裝置介面
img <- image_graph(600, 340, res = 96)

data.list %>% lapply(function(data){
    ggplot(data, aes(gdpPercap, lifeExp, 
             size = pop, color = continent)) +
           scale_size("populati0n", 
             limits = range(gapminder$pop)) + 
           geom_point() + ylim(20, 90) + 
           scale_x_log10(limits = range(gapminder$gdpPercap)) +
           #標題為該分割資料的年份
           ggtitle(data$year) + 
           theme_classic()
})
dev.off()

animation <- image_animate(img, fps = 2)
animation

animation.mark <- image_composite(animation,image_scale(pic3,"100"),offset = "+380+200")
animation.mark

image_write(animation.mark,"gdp.gif") #以gif檔匯出

在R的GDI中處理圖片(以下程式建議在RStudio運行)

先用Magick::image_read讀取圖片,再用Raster::as.rater轉成raster變數,便可用plot函數輸出圖片

frog <- image_read('https://media.kocpc.com.tw/kocpc/2018/01/1517192408-1d049705f439174de7fe71ecffbaeb79.jpg')
frog 

class(frog)
## [1] "magick-image"
#將magick-image變數轉成raster變數
frog.ras <- as.raster(frog)
head(frog.ras)
## [1] "#feffffff" "#fffdffff" "#fffffbff" "#fefefeff" "#fcfefdff" "#d8dad7ff"
#raster變數內容為像素矩陣,plot可直接畫raster
class(frog.ras)
## [1] "raster"
## magick-image繪畫在Viewer,plot則是畫在plots
plot(frog.ras)

#用locator在R-GDI(Plots)中選4點,找出圖表中的點座標(對應橫縱軸數值)
locator(n = 4,type = "n") 

#此時便可用低階繪圖函數處理圖片
rect(11, 15, 189, 189, border = "red", lty = "dashed", lwd = 5)

在R-GDI(Plots)的圖表內疊加圖片

rasterImage() : 將靜圖加到統計圖表,為R內建的函數,可以當作是低階繪圖函數

plot(iris$Sepal.Length) 
locator(n = 4,type = "n")
rasterImage(frog, 0, 6, 29, 8) #位置參數跟rect一樣

grid.raster() : 將靜圖加到統計圖表

需要載入grid套件,低階繪圖函數,位置參數較不同

library(grid)
hist(iris$Sepal.Length)
#位置參數是中心位置的X、Y座標,以及寬跟高,數值都介於0~1之間,是跟整張圖表寬跟高的相對比例
grid.raster(frog,x = 0.82, y = 0.68, width = 0.16, height = 0.25) 

輸出圖形固定寬高比並填滿視窗

利用內建raster套件中的brick函數能讀取本機圖片,並轉成RasterBrick圖形變數,再透過plotRGB輸出圖型

library(raster) #brick跟plotRGB都在raster套件中
gunter <- image_read("https://i.imgur.com/9WWKkxl.png")
gunter

tempfile()  #tempfile()是創建一個新的佔存檔路徑
## [1] "C:\\Users\\yeyut\\AppData\\Local\\Temp\\RtmpAhx6ln\\file22284391ece"
#將圖檔寫到佔存路徑,tiff是點陣圖格式之一,似乎是很彈性的格式
path <- tempfile() 
image_write(gunter, path = path, format = 'tiff')

可用brick讀取圖檔路徑,不能讀取網址或magick-image變數,只能先將magick-image匯出再用brick匯入

gunter.rb <- brick(path) #brick佔存檔路徑

class(gunter.rb)
## [1] "RasterBrick"
## attr(,"package")
## [1] "raster"
head(gunter.rb,2) #將圖檔brick後是像素矩陣
##      file222810f56ecf.1 file222810f56ecf.2 file222810f56ecf.3
## [1,]                  0                  0                  0
## [2,]                  0                  0                  0
## [3,]                  0                  0                  0
## [4,]                  0                  0                  0
##      file222810f56ecf.4
## [1,]                  0
## [2,]                  0
## [3,]                  0
## [4,]                  0
#RasterBrick變數跟Spatial Polygon Data Frame有點像,兩種變數都屬於S4 class,包含數個slots可用@呼叫
str(gunter.rb)
## Formal class 'RasterBrick' [package "raster"] with 12 slots
##   ..@ file    :Formal class '.RasterFile' [package "raster"] with 13 slots
##   .. .. ..@ name        : chr "C:\\Users\\yeyut\\AppData\\Local\\Temp\\RtmpAhx6ln\\file222810f56ecf"
##   .. .. ..@ datanotation: chr "INT1U"
##   .. .. ..@ byteorder   : chr "little"
##   .. .. ..@ nodatavalue : num -Inf
##   .. .. ..@ NAchanged   : logi FALSE
##   .. .. ..@ nbands      : int 4
##   .. .. ..@ bandorder   : chr "BIL"
##   .. .. ..@ offset      : int 0
##   .. .. ..@ toptobottom : logi TRUE
##   .. .. ..@ blockrows   : int [1:4] 346 346 346 346
##   .. .. ..@ blockcols   : int [1:4] 300 300 300 300
##   .. .. ..@ driver      : chr "gdal"
##   .. .. ..@ open        : logi FALSE
##   ..@ data    :Formal class '.MultipleRasterData' [package "raster"] with 14 slots
##   .. .. ..@ values    : logi[0 , 0 ] 
##   .. .. ..@ offset    : num 0
##   .. .. ..@ gain      : num 1
##   .. .. ..@ inmemory  : logi FALSE
##   .. .. ..@ fromdisk  : logi TRUE
##   .. .. ..@ nlayers   : int 4
##   .. .. ..@ dropped   : NULL
##   .. .. ..@ isfactor  : logi FALSE
##   .. .. ..@ attributes: list()
##   .. .. ..@ haveminmax: logi TRUE
##   .. .. ..@ min       : num [1:4] 0 0 0 0
##   .. .. ..@ max       : num [1:4] 255 255 255 255
##   .. .. ..@ unit      : chr ""
##   .. .. ..@ names     : chr [1:4] "file222810f56ecf.1" "file222810f56ecf.2" "file222810f56ecf.3" "file222810f56ecf.4"
##   ..@ legend  :Formal class '.RasterLegend' [package "raster"] with 5 slots
##   .. .. ..@ type      : chr(0) 
##   .. .. ..@ values    : logi(0) 
##   .. .. ..@ color     : logi(0) 
##   .. .. ..@ names     : logi(0) 
##   .. .. ..@ colortable: logi(0) 
##   ..@ title   : chr(0) 
##   ..@ extent  :Formal class 'Extent' [package "raster"] with 4 slots
##   .. .. ..@ xmin: num 0
##   .. .. ..@ xmax: num 300
##   .. .. ..@ ymin: num 0
##   .. .. ..@ ymax: num 346
##   ..@ rotated : logi FALSE
##   ..@ rotation:Formal class '.Rotation' [package "raster"] with 2 slots
##   .. .. ..@ geotrans: num(0) 
##   .. .. ..@ transfun:function ()  
##   ..@ ncols   : int 300
##   ..@ nrows   : int 346
##   ..@ crs     :Formal class 'CRS' [package "sp"] with 1 slot
##   .. .. ..@ projargs: chr NA
##   ..@ history : list()
##   ..@ z       : list()
#用plotRGB繪製RasterBrick變數,隨著視窗大小變化,圖形寬高比例不會跑掉,並總是填滿視窗
plotRGB(gunter.rb)

brick也能讀像素矩陣,可從magick-image中找出像素資訊

##magick.image變數frog[[1]]偷藏著bitmap資訊
frog.bmp <- frog[[1]]
class(frog.bmp)
## [1] "bitmap" "rgb"
#將bitmap的像素資訊轉成像素矩陣
frog.array <- as.integer(frog.bmp)
class(frog.array)
## [1] "array"
#rb.fail <- brick(frog.bmp)
rb <- brick(frog.array) #brick不能讀bitmap變數,卻可讀array
class(rb)
## [1] "RasterBrick"
## attr(,"package")
## [1] "raster"
#asp=高與寬的比值
plotRGB(rb, asp = 1)

讀取PDF檔

image_read() : 讀取pdf失敗,原因不明

# mypdf <- image_read('https://ir.nctu.edu.tw/bitstream/11536/71395/1/342302.pdf')

# mypdf <- image_read('C:/RData/magick.pdf')

套件pdftools :: pdf_render_page()

一次只能讀一頁,無法知道總頁數

library(pdftools)
pdf2bmp <- pdf_render_page('https://cran.r-project.org/web/packages/magick/magick.pdf', page = 1)
head(pdf2bmp)
## [1] ff ff ff ff ff ff
#解析後為點陣圖(bitmap,bmp)
class(pdf2bmp)
## [1] "bitmap" "rgba"
#可以用image_read讀取bmp檔
bmp2png <- image_read(pdf2bmp)
bmp2png

光學字符辨識(Optical Character Recognition,OCR)

image_ocr : 辨識圖片中的字符(由左而右,從上到下)

words.image <- image_read("http://jeroen.github.io/images/testocr.png")
words.image

class(words.image)
## [1] "magick-image"
words.ocr <- magick::image_ocr(words.image)
class(words.ocr)
## [1] "character"
cat(words.ocr)
## This is a lot of 12 point text to test the
## cor code and see if it works on all types
## of file format.
## 
## The quick brown dog jumped over the
## lazy fox. The quick brown dog jumped
## over the lazy fox. The quick brown dog
## jumped over the lazy fox. The quick
## brown dog jumped over the lazy fox.

image_ocr功能來自tesseract套件中ocr函數

library(tesseract)
## Warning: package 'tesseract' was built under R version 3.4.3
tesseract::ocr(words.image) == magick::image_ocr(words.image)
## [1] TRUE

中文字符辨識,錯字不少

chi_words <- image_read('http://farm4.static.flickr.com/3207/3009617589_7be5462002_o.jpg')
chi_words

chi_words.ocr <- image_ocr(chi_words,language = 'chi_tra')
cat(chi_words.ocr)
## 捍衛中華民國台瀉的主權` 促進兩岸脛貿合作 ` 理應是朝野兩黨
## 的共識。 但這段時問以來` 我們看到的是祿營的不理性抗爭〔張銘清
## 事件〕以反藍營的因噎廢食 (強拆抗議人士的國旗﹞ ﹛】 一遣是煽動人民
## 的情緒卻叉不負約束責任的把人民推上火線` 一遣則是過份競中讓人
## 民覺得有賣台之嫌。 卻不見有任何人出來告訴人民`應該如何達到雙
## 贏的局面` 而是放任局勢愈漬愈烈。
## 
## 一直到今天` 兩遣的犢導人才分別發表宣言。 馬英九說會要求員
## 警客氣執法ˋ蔡英文放重話說要和罕非暴力。但這種象徵性的宣告`
## 除了做做形象之外` 對於已燃起的火線` 似乎也沒什麼太大的幫助。
## 那些政治人物都是白痴嗎?還是他們有著更灤遠的打算﹖

無法辨識中文字的話,先跑以下兩行下載繁中跟簡中字庫

# tesseract_download("chi_tra", datapath = NULL, progress = TRUE)
# tesseract_download("chi_sim", datapath = NULL, progress = TRUE)

#其他字庫可參考下列網站:https://github.com/tesseract-ocr/tessdata

辨識pdf

dpi要夠高才能辨識的了,否則就是一堆wwwwwww

pdf.imag <- pdf_render_page('https://cran.r-project.org/web/packages/magick/magick.pdf', page = 1,dpi = 300) %>% image_read 

pdf.imag

pdf.imag %>% image_ocr %>% cat
## 6 ' 9
## Package maglck
## December 1, 2017
## Type Package
## Title Advanced Graphics and Image-Processing in R
## Version 1.6
## Author Jeroen Ooms
## Maintainer Jeroen Ooms <jeroen@berkeley. edu>
## Description Bindings t0 'ImageMagick': the most comprehensive open-source image
## processing library available. Supports many common formats (png, jpeg, tiff,
## pdf, etc) and manipulations (rotate, scale, crop, trim, <U+FB02>ip, blur, etc).
## All operations are vectorized Via the Magick++ STL meaning they operate either
## on a single frame or a series of frames for working with layers, collages,
## 0r animation. In RStudio images are automatically previewed when printed to
## the console, resulting in an interactive editing environment. The latest
## version of the package includes a native graphics device for creating
## in-memory graphics or drawing onto images using pixel coordinates.
## License MIT + <U+FB01>le LICENSE
## URL https : //github. com/ropensci/magick#readme
## BugReports https : //github. com/ropensci/magick/issues
## SystemRequirements ImageMagick++z ImageMagiCk-C++-devel (rpm) 0r
## libmagick++-dev (deb)
## VignetteBuilder knitr
## Imports chp (>= 0.12.12), magrittr, knitr, curl
## LinkingTo chp
## Suggests spelling, methods, rmarkdown, rsvg, webp, png, pdftools,
## ggplot2, raster, rgdal, gapminder, tesseract
## RoxygenNote 6.0.1.9000
## NeedsCompilation yes
## Repository CRAN
## Date/Publication 2017-12-01 17:56:46 UTC
## 1

辨識數統課本casella_berger_statistical_inference

符號無法順利辨識,公式全亂了

stat_inf <- NULL
for(i in 30:32){
    stat_inf <- c(stat_inf, pdf_render_page('https://fsalamri.files.wordpress.com/2015/02/casella_berger_statistical_inference1.pdf', page = i,dpi = 800) %>% image_read %>% image_ocr)
}

cat(stat_inf[1])
## Section 1.1 _ SET THEORY 3
## Complementation: The complement of A, written Ac, isthe set of 3.11 elements
## that are not in A:
## A6 = {a:: 2: ¢ A}.
## Example 1.1.3 (Event operations) Consider the experiment of selecting a. card
## at random from a standard deck and noting its suit: clubs (C), diamonds (D), hearts
## (H), or spades (S). The sample space is
## S = {C, D, H, S},
## and some possible events are
## A = {C,D} and B = {D,H,S}. '
## From these events we can form
## AU B = {C,D,H,S}, AnB = {D}, and AC 2 {H,S}.
## Furthermore, notice that A U B = S (the event 5) and (A U B)C = (2), where (2) denotes
## the empty set (the set consisting of no elements). ||
## The elementary set operations can be combined, somewhat akin to the way addition
## and multiplication can be combined. As long as we are careful, we can treat sets as if
## they were numbers. We can now state the following useful properties of set operations.
## Theorem 1.1.4 Forany three events, A, B, and C, de<U+FB01>ned on a sample space S ,
## a. Commutativity A U B = B U A,
## A<U+FB02>BzB<U+FB02>A;
## b. Associativity A U (B U C) = (A U B) U C,
## A<U+FB02>(B<U+FB02>C) = (A<U+FB02>B)<U+FB02>C;
## c. Distributive Laws A n (B U C) = (A n B) U (A n C),
## AU(B<U+FB02>C) = (AUB)<U+FB02>(AUC);
## d. DeMorgan’s Laws (A U B)c 2 Ac 0 8“,
## (An B)° = Ac UBC.
## Proof: The proof of much of this theorem is left as Exercise 1.3. Also, Exercises 1.9
## and 1.10 generalize the theorem. To illustrate the technique, however, we will prove
## the Distributive Law:
## An(BLJC) = (AnB)LJ(AnC).
## (You might be familiar with the use of Venn diagrams to “prove” theorems in set
## theory. We caution that although Venn diagrams are sometimes helpful in visualizing
## a situation, they do not constitute a formal proof.) To prove that two sets are equal,
## it must be demonstrated that each set contains the other. Formally, then
## A<U+FB02>(BUC) = {3:6er EAande (BUC)};
## (A<U+FB02>B)U(A<U+FB02>C) = {2: 6 5:3: 6 (A<U+FB02>B) ora: E (A<U+FB02>C)}.